package com.hnx.admin.aurora.captcha.config;

import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.util.Config;
import com.hnx.admin.aurora.captcha.api.CaptchaAPI;
import com.hnx.admin.aurora.captcha.core.CaptchaProperties;
import com.hnx.admin.aurora.config.AppConfig;
import com.hnx.admin.aurora.redis.RedisCache;
import com.hnx.admin.aurora.utils.Base64Util;
import com.hnx.admin.aurora.web.exception.captcha.CaptchaImageException;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.FastByteArrayOutputStream;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

import static com.google.code.kaptcha.Constants.*;

/*
创建人： 倔强的头发
创建时间：2025/6/14
功能描述:

*/
@Configuration
@RequiredArgsConstructor
public class KatchaConfig implements CaptchaAPI {
    private final CaptchaProperties captchaProperties;
    private final AppConfig appConfig;
    private final RedisCache redisCache;
    @Bean
    @ConditionalOnProperty(prefix = "admin",name = "captchaType",havingValue = "char")
    public Producer createCharProducer(){
        Properties props = new Properties();
        CaptchaProperties.CharConfig charConfig = captchaProperties.getCharConfig();
        props.setProperty(KAPTCHA_IMAGE_WIDTH, String.valueOf(charConfig.getWidth()));
        // 验证码图片高度 默认为50
        props.setProperty(KAPTCHA_IMAGE_HEIGHT, String.valueOf(charConfig.getHeight()));
        props.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, String.valueOf(charConfig.getLength()));
        props.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, charConfig.getFontColor());
        props.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, String.valueOf(charConfig.getFontSize()));
        props.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_STRING,charConfig.getSource());
        props.setProperty(KAPTCHA_NOISE_IMPL, NO_NOISE_IMPL);
        props.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, SHADOW_GIMPY_IMPL);
        return new Config(props).getProducerImpl();
    }
    @Bean
    @ConditionalOnProperty(prefix = "admin",name = "captchaType",havingValue = "math")
    public Producer createMathProducer(){
        Properties props = new Properties();
        CaptchaProperties.MathConfig mathConfig = captchaProperties.getMathConfig();
        props.setProperty(KAPTCHA_IMAGE_WIDTH, String.valueOf(mathConfig.getWidth()));
        // 验证码图片高度 默认为50
        props.setProperty(KAPTCHA_IMAGE_HEIGHT, String.valueOf(mathConfig.getHeight()));
        props.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.hnx.admin.aurora.captcha.core.KaptchaTextCreator");
        props.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, mathConfig.getFontColor());
        props.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, String.valueOf(mathConfig.getFontSize()));
        props.setProperty(KAPTCHA_NOISE_COLOR, "white");
        props.setProperty(KAPTCHA_NOISE_IMPL, NO_NOISE_IMPL);
        props.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, SHADOW_GIMPY_IMPL);
        return new Config(props).getProducerImpl();
    }
    private String createText(Producer producer,String uuid){

        String capText = producer.createText();
        String code = capText;
        if(appConfig.getCaptchaType().equals("math")){
            int index = capText.lastIndexOf("@");
            code = capText.substring(index + 1);
            capText = capText.substring(0, index);
        }
        redisCache.setCacheObject(captchaKey(uuid),code,CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        return capText;
    }
    public String createCode(Producer producer,String uuid){
        String capText = createText(producer,uuid);
        BufferedImage image = producer.createImage(capText);
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try {
            ImageIO.write(image, "jpg", os);
        } catch (IOException e) {
            throw new CaptchaImageException();
        }
        finally {
            os.close();
        }
        return Base64Util.encode(os.toByteArray());
    }
}
